const { DataTypes } = require('sequelize');
const { sequelize } = require('../config/database');
const logger = require('../config/logger');

// 考试模型定义
const Exam = sequelize.define('Exam', {
  id: {
    type: DataTypes.UUID,
    defaultValue: DataTypes.UUIDV4,
    primaryKey: true,
    comment: '考试唯一标识'
  },
  
  // 基本信息
  title: {
    type: DataTypes.STRING(200),
    allowNull: false,
    validate: {
      len: [1, 200]
    },
    comment: '考试标题'
  },
  
  description: {
    type: DataTypes.TEXT,
    allowNull: true,
    comment: '考试描述'
  },
  
  instructions: {
    type: DataTypes.TEXT,
    allowNull: true,
    comment: '考试说明'
  },
  
  // 关联信息
  courseId: {
    type: DataTypes.UUID,
    allowNull: true,
    comment: '关联课程ID'
  },
  
  teacherId: {
    type: DataTypes.UUID,
    allowNull: false,
    comment: '创建教师ID'
  },
  
  // 考试类型和分类
  type: {
    type: DataTypes.ENUM('quiz', 'midterm', 'final', 'practice', 'certification'),
    allowNull: false,
    defaultValue: 'quiz',
    comment: '考试类型'
  },
  
  category: {
    type: DataTypes.STRING(100),
    allowNull: true,
    comment: '考试分类'
  },
  
  // 难度级别
  level: {
    type: DataTypes.ENUM('beginner', 'intermediate', 'advanced', 'expert'),
    allowNull: false,
    defaultValue: 'beginner',
    comment: '考试难度级别'
  },
  
  // 状态信息
  status: {
    type: DataTypes.ENUM('draft', 'published', 'archived', 'deleted'),
    allowNull: false,
    defaultValue: 'draft',
    comment: '考试状态'
  },
  
  publishedAt: {
    type: DataTypes.DATE,
    allowNull: true,
    comment: '发布时间'
  },
  
  // 时间设置
  duration: {
    type: DataTypes.INTEGER,
    allowNull: false,
    defaultValue: 60,
    validate: {
      min: 1,
      max: 480 // 最长8小时
    },
    comment: '考试时长（分钟）'
  },
  
  startTime: {
    type: DataTypes.DATE,
    allowNull: true,
    comment: '考试开始时间'
  },
  
  endTime: {
    type: DataTypes.DATE,
    allowNull: true,
    comment: '考试结束时间'
  },
  
  // 考试设置
  totalQuestions: {
    type: DataTypes.INTEGER,
    allowNull: false,
    defaultValue: 0,
    comment: '题目总数'
  },
  
  totalScore: {
    type: DataTypes.DECIMAL(5, 2),
    allowNull: false,
    defaultValue: 100.00,
    comment: '总分'
  },
  
  passingScore: {
    type: DataTypes.DECIMAL(5, 2),
    allowNull: false,
    defaultValue: 60.00,
    comment: '及格分数'
  },
  
  // 考试规则
  maxAttempts: {
    type: DataTypes.INTEGER,
    allowNull: false,
    defaultValue: 1,
    validate: {
      min: 1,
      max: 10
    },
    comment: '最大尝试次数'
  },
  
  shuffleQuestions: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: false,
    comment: '是否打乱题目顺序'
  },
  
  shuffleOptions: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: false,
    comment: '是否打乱选项顺序'
  },
  
  showResults: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: true,
    comment: '是否显示结果'
  },
  
  showCorrectAnswers: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: false,
    comment: '是否显示正确答案'
  },
  
  allowReview: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: true,
    comment: '是否允许回顾'
  },
  
  allowBacktrack: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: true,
    comment: '是否允许返回上一题'
  },
  
  requireProctoring: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: false,
    comment: '是否需要监考'
  },
  
  preventCheating: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: false,
    comment: '是否启用防作弊'
  },
  
  // 访问控制
  isPublic: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: false,
    comment: '是否公开'
  },
  
  requiresPassword: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: false,
    comment: '是否需要密码'
  },
  
  password: {
    type: DataTypes.STRING(255),
    allowNull: true,
    comment: '考试密码'
  },
  
  allowedUsers: {
    type: DataTypes.JSON,
    allowNull: true,
    defaultValue: [],
    comment: '允许参加的用户ID列表'
  },
  
  // 统计信息
  attemptCount: {
    type: DataTypes.INTEGER,
    allowNull: false,
    defaultValue: 0,
    comment: '参与次数'
  },
  
  completionCount: {
    type: DataTypes.INTEGER,
    allowNull: false,
    defaultValue: 0,
    comment: '完成次数'
  },
  
  averageScore: {
    type: DataTypes.DECIMAL(5, 2),
    allowNull: false,
    defaultValue: 0.00,
    comment: '平均分数'
  },
  
  highestScore: {
    type: DataTypes.DECIMAL(5, 2),
    allowNull: false,
    defaultValue: 0.00,
    comment: '最高分数'
  },
  
  lowestScore: {
    type: DataTypes.DECIMAL(5, 2),
    allowNull: true,
    comment: '最低分数'
  },
  
  passRate: {
    type: DataTypes.DECIMAL(5, 2),
    allowNull: false,
    defaultValue: 0.00,
    comment: '通过率（百分比）'
  },
  
  // 证书设置
  generateCertificate: {
    type: DataTypes.BOOLEAN,
    allowNull: false,
    defaultValue: false,
    comment: '是否生成证书'
  },
  
  certificateTemplate: {
    type: DataTypes.TEXT,
    allowNull: true,
    comment: '证书模板'
  },
  
  // 扩展字段
  settings: {
    type: DataTypes.JSON,
    allowNull: true,
    defaultValue: {},
    comment: '考试设置'
  },
  
  metadata: {
    type: DataTypes.JSON,
    allowNull: true,
    defaultValue: {},
    comment: '扩展元数据'
  }
}, {
  tableName: 'exams',
  timestamps: true,
  paranoid: true, // 软删除
  indexes: []
});

// 实例方法
// 检查考试是否可以参加
Exam.prototype.canTake = function(userId) {
  const now = new Date();
  
  // 检查考试状态
  if (this.status !== 'published') {
    return { canTake: false, reason: '考试未发布' };
  }
  
  // 检查时间范围
  if (this.startTime && now < this.startTime) {
    return { canTake: false, reason: '考试尚未开始' };
  }
  
  if (this.endTime && now > this.endTime) {
    return { canTake: false, reason: '考试已结束' };
  }
  
  // 检查访问权限
  if (!this.isPublic && this.allowedUsers && this.allowedUsers.length > 0) {
    if (!this.allowedUsers.includes(userId)) {
      return { canTake: false, reason: '无权限参加此考试' };
    }
  }
  
  return { canTake: true };
};

// 验证考试密码
Exam.prototype.validatePassword = function(password) {
  if (!this.requiresPassword) {
    return true;
  }
  return this.password === password;
};

// 检查用户是否已达到最大尝试次数
Exam.prototype.hasReachedMaxAttempts = async function(userId) {
  // 这里需要查询考试记录表
  // 暂时返回false
  return false;
};

// 获取用户的考试记录
Exam.prototype.getUserAttempts = async function(userId) {
  // 这里需要查询考试记录表
  // 暂时返回空数组
  return [];
};

// 增加参与次数
Exam.prototype.incrementAttemptCount = async function() {
  return this.increment('attemptCount');
};

// 增加完成次数
Exam.prototype.incrementCompletionCount = async function() {
  return this.increment('completionCount');
};

// 更新统计信息
Exam.prototype.updateStatistics = async function(score) {
  const updates = {};
  
  // 更新最高分
  if (score > this.highestScore) {
    updates.highestScore = score;
  }
  
  // 更新最低分
  if (this.lowestScore === null || score < this.lowestScore) {
    updates.lowestScore = score;
  }
  
  // 重新计算平均分和通过率（这里简化处理）
  const totalScore = this.averageScore * this.completionCount + score;
  const newCompletionCount = this.completionCount + 1;
  updates.averageScore = Math.round((totalScore / newCompletionCount) * 100) / 100;
  
  // 计算通过率
  const passCount = score >= this.passingScore ? 1 : 0;
  const currentPassCount = Math.round((this.passRate / 100) * this.completionCount);
  updates.passRate = Math.round(((currentPassCount + passCount) / newCompletionCount) * 10000) / 100;
  
  return this.update(updates);
};

// 发布考试
Exam.prototype.publish = async function() {
  return this.update({
    status: 'published',
    publishedAt: new Date()
  });
};

// 归档考试
Exam.prototype.archive = async function() {
  return this.update({
    status: 'archived'
  });
};

// 获取考试统计信息
Exam.prototype.getStatistics = function() {
  return {
    totalQuestions: this.totalQuestions,
    totalScore: this.totalScore,
    passingScore: this.passingScore,
    attemptCount: this.attemptCount,
    completionCount: this.completionCount,
    completionRate: this.attemptCount > 0 ? 
      Math.round((this.completionCount / this.attemptCount) * 100) : 0,
    averageScore: this.averageScore,
    highestScore: this.highestScore,
    lowestScore: this.lowestScore,
    passRate: this.passRate
  };
};

// 检查是否在考试时间内
Exam.prototype.isActive = function() {
  const now = new Date();
  
  if (this.status !== 'published') {
    return false;
  }
  
  if (this.startTime && now < this.startTime) {
    return false;
  }
  
  if (this.endTime && now > this.endTime) {
    return false;
  }
  
  return true;
};

// 获取剩余时间
Exam.prototype.getRemainingTime = function() {
  if (!this.endTime) {
    return null;
  }
  
  const now = new Date();
  const remaining = this.endTime.getTime() - now.getTime();
  
  return remaining > 0 ? remaining : 0;
};

// 类方法
// 根据课程查找考试
Exam.findByCourse = function(courseId, options = {}) {
  return this.findAll({
    where: {
      courseId,
      status: 'published'
    },
    ...options
  });
};

// 根据教师查找考试
Exam.findByTeacher = function(teacherId, options = {}) {
  return this.findAll({
    where: {
      teacherId
    },
    ...options
  });
};

// 搜索考试
Exam.search = function(keyword, options = {}) {
  return this.findAll({
    where: {
      [sequelize.Sequelize.Op.or]: [
        {
          title: {
            [sequelize.Sequelize.Op.like]: `%${keyword}%`
          }
        },
        {
          description: {
            [sequelize.Sequelize.Op.like]: `%${keyword}%`
          }
        }
      ],
      status: 'published'
    },
    ...options
  });
};

// 获取公开考试
Exam.getPublic = function(options = {}) {
  return this.findAll({
    where: {
      status: 'published',
      isPublic: true
    },
    ...options
  });
};

// 获取用户可参加的考试
Exam.getAvailableForUser = function(userId, options = {}) {
  const now = new Date();
  
  return this.findAll({
    where: {
      status: 'published',
      [sequelize.Sequelize.Op.or]: [
        { isPublic: true },
        {
          allowedUsers: {
            [sequelize.Sequelize.Op.contains]: [userId]
          }
        }
      ],
      [sequelize.Sequelize.Op.or]: [
        { startTime: null },
        { startTime: { [sequelize.Sequelize.Op.lte]: now } }
      ],
      [sequelize.Sequelize.Op.or]: [
        { endTime: null },
        { endTime: { [sequelize.Sequelize.Op.gte]: now } }
      ]
    },
    ...options
  });
};

// 根据类型查找考试
Exam.findByType = function(type, options = {}) {
  return this.findAll({
    where: {
      type,
      status: 'published'
    },
    ...options
  });
};

// 根据难度级别查找考试
Exam.findByLevel = function(level, options = {}) {
  return this.findAll({
    where: {
      level,
      status: 'published'
    },
    ...options
  });
};

// 获取即将开始的考试
Exam.getUpcoming = function(options = {}) {
  const now = new Date();
  
  return this.findAll({
    where: {
      status: 'published',
      startTime: {
        [sequelize.Sequelize.Op.gt]: now
      }
    },
    order: [['startTime', 'ASC']],
    ...options
  });
};

// 获取正在进行的考试
Exam.getOngoing = function(options = {}) {
  const now = new Date();
  
  return this.findAll({
    where: {
      status: 'published',
      [sequelize.Sequelize.Op.or]: [
        { startTime: null },
        { startTime: { [sequelize.Sequelize.Op.lte]: now } }
      ],
      [sequelize.Sequelize.Op.or]: [
        { endTime: null },
        { endTime: { [sequelize.Sequelize.Op.gte]: now } }
      ]
    },
    ...options
  });
};

// 钩子函数
// 发布时设置发布时间
Exam.beforeUpdate((exam) => {
  if (exam.changed('status') && exam.status === 'published' && !exam.publishedAt) {
    exam.publishedAt = new Date();
  }
});

// 记录考试创建日志
Exam.afterCreate((exam) => {
  logger.business('考试创建', {
    examId: exam.id,
    title: exam.title,
    teacherId: exam.teacherId,
    courseId: exam.courseId,
    type: exam.type,
    status: exam.status
  });
});

// 记录考试更新日志
Exam.afterUpdate((exam) => {
  const changes = exam.changed();
  if (changes && changes.length > 0) {
    logger.business('考试更新', {
      examId: exam.id,
      changes: changes.filter(field => !['updatedAt', 'attemptCount', 'completionCount'].includes(field))
    });
  }
});

// 记录考试删除日志
Exam.afterDestroy((exam) => {
  logger.business('考试删除', {
    examId: exam.id,
    title: exam.title,
    teacherId: exam.teacherId,
    courseId: exam.courseId
  });
});

module.exports = Exam;